package com.lensyn.generator.plugins;

import com.lensyn.generator.handler.ServiceNameHandler;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Service impl 生成器
 * @author xiaob@lensysn.com
 * @date 2016/12/20
 * @see CUIDPlugin#generateServiceInterfaceImpl(IntrospectedTable, TopLevelClass, Interface)
 */
public class GenerateServiceImpl {

    protected IntrospectedTable introspectedTable;

    protected TopLevelClass dtoClass;

    protected ServiceNameHandler serviceNameHandler;

    protected Interface anInterface;

    public GenerateServiceImpl(IntrospectedTable introspectedTable, TopLevelClass dtoClass, ServiceNameHandler serviceNameHandler, Interface anInterface) {
        this.introspectedTable = introspectedTable;
        this.dtoClass = dtoClass;
        this.serviceNameHandler = serviceNameHandler;
        this.anInterface = anInterface;
    }

    public TopLevelClass generateImpl() {
        TopLevelClass serviceImpl = new TopLevelClass(serviceNameHandler.serviceImlName(
                introspectedTable.getFullyQualifiedTable().getIntrospectedTableName()));
        serviceImpl.setVisibility(JavaVisibility.PUBLIC);

        serviceImpl.addImportedType("org.slf4j.Logger");
        serviceImpl.addImportedType("org.slf4j.LoggerFactory");
        serviceImpl.addImportedType("org.springframework.beans.factory.annotation.Autowired");
        serviceImpl.addImportedType("org.springframework.stereotype.Service");
        serviceImpl.addImportedType(dtoClass.getType());
        serviceImpl.addImportedType(anInterface.getType());
        serviceImpl.addImportedType("java.util.List");

        serviceImpl.addAnnotation("@Service");

        serviceImpl.addSuperInterface(anInterface.getType());


        List<Field> fields = addFields(serviceImpl);
        for (Field field : fields) {
            serviceImpl.addField(field);
        }

        List<Method> methods = addMethods();
        for (Method method : methods) {
            serviceImpl.addMethod(method);
        }

        NameUtils.addClassComment(serviceImpl, introspectedTable, " Service Impl");
        return serviceImpl;
    }

    private List<Method> addMethods() {
        List<Method> interfaceMethods = anInterface.getMethods();

        List<Method> result = new ArrayList<Method>();
        for (Method face : interfaceMethods) {
            Method method = new Method(face.getName());
            method.setReturnType(face.getReturnType());
            method.setVisibility(JavaVisibility.PUBLIC);
            for (Parameter parameter : face.getParameters()) {
                method.addParameter(parameter);
            }
            FullyQualifiedJavaType returnType = method.getReturnType();


            method.addBodyLine("//todo Do something");

            result.add(method);

            if (returnType == null) {
                continue;
            }
            if (!returnType.isPrimitive()) {
                method.addBodyLine("return null;");
                continue;
            }

            if ("int".equals(returnType.getFullyQualifiedName())) {
                method.addBodyLine("return 0; ");
            } else if ("boolean".equals(returnType.getFullyQualifiedName())) {
                method.addBodyLine("return false;");
            }


        }

        return result;
    }

    private List<Field> addFields(TopLevelClass serviceImpl) {
        List<Field> fields = new ArrayList<Field>();

        Field logger = NameUtils.logger(serviceImpl.getType().getShortName());

        fields.add(logger);
        return fields;
    }


}
